/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.figures;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.text.FlowPage;
import org.eclipse.draw2d.text.TextFlow;

import com.cea.papyrus.diagraminterchange2.di2.GraphElement;

/**
 * @author Andreas Limyr
 * @author frankd@ifi.uio.no
 */
public class InteractionFigure extends AnchoringFigure {

    private static final Dimension DEFAULT_SIZE = new Dimension(500, 400);

    private TextFlow text;
    private TextFlow stereotypes;
    private FlowPage titleFlow;

    public InteractionFigure() {
        setBorder(new FragmentBorder());
        setLayoutManager(new XYLayout());
        setBackgroundColor(ColorConstants.listBackground);
        setOpaque(true);

        text = new TextFlow("");
        stereotypes = new TextFlow("");
        titleFlow = new FlowPage();
        titleFlow.add(stereotypes);
        titleFlow.add(new TextFlow("  "));
        titleFlow.add(new TextFlow("sd"));
        titleFlow.add(new TextFlow("  "));
        titleFlow.add(text);
        add(titleFlow);
    }

    public Rectangle getPreferredBounds(Rectangle suggestedBounds) {
        if (suggestedBounds.width == 0)
            return new Rectangle(suggestedBounds.getLocation(), DEFAULT_SIZE);
        else
            return suggestedBounds;
    }

    public Dimension getPreferredSize(int w, int h) {
        Dimension prefSize = super.getPreferredSize(w, h);
        Dimension defaultSize = new Dimension(200, 100);
        prefSize.union(defaultSize);
        return prefSize;
    }

    protected void paintFigure(Graphics graphics) {
        titleFlow.setFont(this.getFont());
        titleFlow.setForegroundColor(this.getFontColor());
        Rectangle rect = getBounds().getCopy();
        rect.crop(new Insets(2, 0, 2, 0));
        graphics.setBackgroundColor(this.getBackgroundColor());
        graphics.setForegroundColor(this.getForegroundColor());
        graphics.fillRectangle(rect);
        ((FragmentBorder) getBorder()).setBackgroundColor(this.getBackgroundColor());
        ((FragmentBorder) getBorder()).setColor(this.getBorderColor());
        ((FragmentBorder) getBorder()).paintLabelBackground(this, graphics);
    }

    public void validate() {
        if (isValid())
            return;
        this.invalidateTree();
        super.validate();

        Dimension prefSize = titleFlow.getPreferredSize();
        if (!titleFlow.getSize().equals(prefSize)) {
            titleFlow.setSize(prefSize);
        }
        updateAnchors();
    }

    @Override
    protected boolean useLocalCoordinates() {
        return true; // TODO Investigate if returning false avoids
        // absolute/local coversions
    }

    // Called by the FragmentBorder to paint a frame label border of the
    // correct size
    public Rectangle getLocalTextBounds() {
        return text.getBounds().getCopy();
    }

    // --- ILabeledFigure ---

    public Rectangle getLabelBounds() {
        Rectangle rect = text.getClientArea().getCopy();
        text.translateToAbsolute(rect);
        return rect;
    }

    public void setLabel(String labelText) {
        text.setText(labelText);
        repaint();
    }

    // --- Anchor contribution ---

    private AnchorPolicy anchorPolicy;

    public AnchorPolicy getAnchorPolicy() {
        if (anchorPolicy == null)
            anchorPolicy = new InteractionAnchorPolicy();
        return anchorPolicy;
    }

    public Rectangle getAnchorContributionBounds(IFigure figure) {
        int start;
        if (getBorder() != null)
            start = ((FragmentBorder) getBorder()).getLabelHeight(this);
        else
            start = 0;
        return new Rectangle(0, start, getSize().width, getSize().height - start - 3);
    }

    public int[] contributeAnchors(IFigure figure, int y) {
        return new int[] {
                0, getSize().width - 1
        };
    }

    /**
     * @see com.cea.papyrus.diagram.sequence.sedi.figures.SeDiSubpartFigure#refreshStereotypes(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
     */
    @Override
    public void refreshStereotypes(GraphElement graphElement) {
        super.refreshStereotypes(graphElement);
        this.stereotypes.setText(this.getStereotypesLabel());
    }
}
